﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Drawing.Printing;
using Watchy.Properties;

namespace Watchy
{
    public partial class WatchyForm : Form
    {
        System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();

        public WatchyForm()
        {
            InitializeComponent();
            this.checkForUpdatesToolStripMenuItem.Enabled = false;
            stopwatchBindingSource.DataSource = stopwatch;
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            Start();
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            Stop();
        }

        private void btnReset_Click(object sender, EventArgs e)
        {
            Reset();
        }

        private void btnLap_Click(object sender, EventArgs e)
        {
            Lap();
        }

        private void btnSplit_Click(object sender, EventArgs e)
        {
            Split();
        }

        private void updateFormTimer_Tick(object sender, EventArgs e)
        {
            stopwatchBindingSource.ResetCurrentItem();
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            using (AboutForm frm = new AboutForm())
                frm.ShowDialog(this);
        }

        private void startToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Start();
        }

        private void stopToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Stop();
        }

        private void resetToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Reset();
        }

        private void lapToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Lap();
        }

        private void splitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Split();
        }

        private void Start()
        {
            updateFormTimer.Start();
            stopwatch.Start();
        }

        private void Stop()
        {
            bool wasRunning = stopwatch.IsRunning;
            stopwatch.Stop();
            if (wasRunning)
                this.lstLaps.Items.Add(stopwatch.Elapsed);
            updateFormTimer.Stop();
        }

        private void Reset()
        {
            lstLaps.Items.Clear();
            bool running = stopwatch.IsRunning;
            stopwatch.Reset();
            stopwatchBindingSource.ResetCurrentItem();
            if (running)
                Start();
        }

        private void Split()
        {
            if (stopwatch.IsRunning)
                lstLaps.Items.Add(stopwatch.Elapsed);
        }

        private void Lap()
        {
            if (stopwatch.IsRunning)
            {
                lstLaps.Items.Add(stopwatch.Elapsed);
                stopwatch.Reset();
                stopwatch.Start();
            }
        }

        private void checkForUpdatesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //TODO: Integrate an update framework, possible UpdateDotNet.
            //if (updater.CheckForUpdate())
            //{
            //    DialogResult updateResult = MessageBox.Show("A new version is available. Do you want to update?", "New Version Available", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            //    if (updateResult == DialogResult.Yes)
            //        deploy.Update();
            //}
            //else
            //    MessageBox.Show("No new versions available.", "No New Version", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            using (SaveFileDialog dlg = new SaveFileDialog())
            {
                if (dlg.ShowDialog() == DialogResult.OK)
                {
                    using (StreamWriter writer = new StreamWriter(dlg.FileName))
                    {
                        TimeSpan total = new TimeSpan();
                        int count = 0;
                        foreach (TimeSpan tspan in this.lstLaps.Items)
                        {
                            count++;
                            writer.WriteLine(string.Format("{0}. {1}", count, tspan));
                            total = total.Add(tspan);
                        }
                        writer.WriteLine("-------------------");
                        writer.WriteLine(string.Format("Total: {0}", total));
                    }
                }
            }
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void printToolStripMenuItem_Click(object sender, EventArgs e)
        {
            using (PrintDialog dlg = new PrintDialog())
            {
                dlg.Document = this.printDocument1;
                if (dlg.ShowDialog() == DialogResult.OK)
                {
                    this.printDocument1.Print();
                }
            }
        }

        private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
        {
            TimeSpan total = new TimeSpan();
            int count = 0;
            RectangleF pageBounds = e.PageSettings.PrintableArea;
            pageBounds.Offset((float)e.PageSettings.Margins.Left, (float)e.PageSettings.Margins.Top);
            PointF lineStart = pageBounds.Location;
            int numberOfDigits = (this.lstLaps.Items.Count + 1).ToString().Length;
            string line = string.Empty;
            foreach (TimeSpan tspan in this.lstLaps.Items)
            {
                line = string.Format("{0}. {1}", (++count).ToString().PadLeft(numberOfDigits, '0'), tspan);
                lineStart = DrawLineToPrinter(line, lineStart, e.Graphics);
                total = total.Add(tspan);
            }
            lineStart = DrawLineToPrinter(GetPrintSeperator(line.Length), lineStart, e.Graphics);
            DrawLineToPrinter(string.Format("{0}: {1}", "T".PadLeft(numberOfDigits, 'T'), total), lineStart, e.Graphics);
        }

        private string GetPrintSeperator(int length)
        {
            StringBuilder s = new StringBuilder(length);
            s.Append('-', length);
            return s.ToString();
        }

        private PointF DrawLineToPrinter(string line, PointF lineStart, Graphics printerGraphics)
        {
            Font font = Settings.Default.PrinterFont;
            printerGraphics.DrawString(line, font, Brushes.Black, lineStart);
            lineStart.Y = lineStart.Y + printerGraphics.MeasureString(line, this.Font).Height + 4;
            return lineStart;
        }

        private void printPreviewToolStripMenuItem_Click(object sender, EventArgs e)
        {
            using (PrintPreviewDialog dlg = new PrintPreviewDialog())
            {
                dlg.Document = this.printDocument1;
                dlg.ShowDialog();
            }
        }

        private void printerFontToolStripMenuItem_Click(object sender, EventArgs e)
        {
            using (FontDialog dlg = new FontDialog())
            {
                dlg.FixedPitchOnly = true;
                dlg.ScriptsOnly = true;
                dlg.Font = Settings.Default.PrinterFont;
                if (dlg.ShowDialog() == DialogResult.OK)
                {
                    Settings.Default.PrinterFont = dlg.Font;
                    Settings.Default.Save();
                }
            }
        }
    }
}